function getRoleOptions(selectedRoles) {
    var roles = {};
    for( var rid in gConfTroopMatchRole ) {
        if( selectedRoles.indexOf(+rid) < 0 ) {
            roles[rid] = 1;
        }
    }

    var options = [];
    for( var i=1; i<=3; i++ ) {
        var rid = common.wRand(roles);
        options.push(+rid);
        delete roles[rid];
    }

    return options;
}

exports.get_top = function(player, req, resp, onHandled) {
    if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
        resp.code = 1; resp.desc = 'level not reach';
        onHandled();
        return;
    }

    var troopMatch = player.getTroopMatch(true);

    // 返回奖励
    req.args.name = player.user.info.un;
    req.args.headpic = common.handleHeadpicParseException(player.user.info.headpic);
    req.args.score = troopMatch.week_score;
    requestCloud(req, resp, function(){
        if( resp.code == 0 ) {
            if( resp.data.reward ) {
                resp.data.awards = player.addAwards([gConfTroopMatchRank[resp.data.reward].Award1]); 
            }
            resp.data.troop_match = troopMatch;
        }
        onHandled();
    });
}

exports.clear_time = function(player, req, resp, onHandled) {
    do {
        if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var troopMatch = player.getTroopMatch(true);
        if( !player.costResource('cash', gConfGlobal.TroopMatchClearCashCost) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        troopMatch.time = 0;
        player.markDirty('troop_match.time');

        resp.data.cash = -gConfGlobal.TroopMatchClearCashCost;
        
    }while(false);

    onHandled();
}

exports.enter = function(player, req, resp, onHandled) {
    do {
        if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var troopMatch = player.getTroopMatch(true);
        if( (common.getTime() - troopMatch.time + 10) < gConfGlobal.TroopMatchColdTime ) {
            resp.code = 1; resp.desc = 'colding'; break;
        }

        if( troopMatch.clear_time >= gConfGlobal.TroopMatchEnterTimes ) {
            resp.code = 1; resp.desc = 'no time to enter'; break;
        }

        if( troopMatch.roles.length > 0 || troopMatch.options.length > 0 ) {
            resp.code = 1; resp.desc = 'have enter'; break;
        }

        troopMatch.clear_time += 1;
        player.markDirty('troop_match.clear_time');

        troopMatch.options = getRoleOptions(troopMatch.roles);
        player.markDirty('troop_match.options');

        resp.data.options = troopMatch.options;

    }while(false);

    onHandled();
}

exports.select_role = function(player, req, resp, onHandled) {
    do {
        if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var troopMatch = player.getTroopMatch();
        if( troopMatch.options.indexOf(req.args.rid) < 0 ) {
            resp.code = 1; resp.desc = 'invalid rid'; break;
        }

        troopMatch.roles.push(req.args.rid);

        if( troopMatch.roles.length < 7 ) {
            troopMatch.options = getRoleOptions(troopMatch.roles);
        }else{
            troopMatch.options = [];
        }

        player.markDirty('troop_match.roles');
        player.markDirty('troop_match.options');

        resp.data.options = troopMatch.options;

    }while(false);
    
    onHandled();
}

exports.save_team = function(player, req, resp, onHandled) {
    do {
        if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var troopMatch = player.getTroopMatch(true);
        if( troopMatch.roles.length < 7 ) {
            resp.code = 1; resp.desc = 'not enough role'; break;
        }
        
        var valid = true;
        var team = req.args.team;
        var existRole = [];
        var validTeam = {};
        for( var pos=0; pos<9; pos++ ) {
            var rid = team[pos];  
            if( !rid ) {
                rid = 0;
            }

            validTeam[pos] = rid;
            if( !rid ) continue;

            if( troopMatch.roles.indexOf(rid) < 0 ) {
                valid = false;
                break;
            }

            if( existRole.indexOf(rid) >= 0 ) {
                valid = false;
                break;
            }

            existRole.push(rid);
        }

        if( !valid || existRole.length <= 0 ) {
            resp.code = 1; resp.desc = 'invalid team'; break;
        }

        troopMatch.team = validTeam;
        player.markDirty('troop_match.team');

    }while(false);

    onHandled();
}

exports.match = function(player, req, resp, onHandled) {
    var troopMatch = player.getTroopMatch(true);
    do {
        if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( troopMatch.roles.length < 7 ) {
            resp.code = 1; resp.desc = 'not enough role'; break;
        }

        if( Object.keys(troopMatch.team).length <= 0 ) {
            resp.code = 1; resp.desc = 'not save team'; break;
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }
    
    req.args.team = troopMatch.team;
    req.args.name = player.user.info.un;
    req.args.headpic = common.handleHeadpicParseException(player.user.info.headpic);
    req.args.win = troopMatch.cur_win;

    requestCloud(req, resp, function(){
        if( resp.code == 0 ) {
            player.troopMatchFight(resp.data.battle, resp); 
        }

        resp.data.troop_match = troopMatch;
        onHandled();
    });
}

exports.retry = function(player, req, resp, onHandled) {
    do {
        if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( player.user.status.cash < gConfGlobal.TroopMatchRetryCashCost ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }
        
        var troopMatch = player.getTroopMatch(true);
        if( troopMatch.roles.length < 7 ) {
            resp.code = 1; resp.desc = 'not enough role'; break;
        }

        if( Object.keys(troopMatch.team).length <= 0 ) {
            resp.code = 1; resp.desc = 'not save team'; break;
        }
    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    req.args.team = troopMatch.team;
    req.args.name = player.user.info.un;
    req.args.headpic = common.handleHeadpicParseException(player.user.info.headpic);

    requestCloud(req, resp, function() {
        if( resp.code == 0 ) {
            player.troopMatchFight(resp.data.battle, resp); 
        }

        player.costResource('cash', gConfGlobal.TroopMatchRetryCashCost);

        resp.data.cash = -gConfGlobal.TroopMatchRetryCashCost;
        resp.data.troop_match = troopMatch;
        onHandled();
    });
}

exports.give_up = function(player, req, resp, onHandled) {
    player.troopMatchOver();
    resp.data.troop_match = player.getTroopMatch();

    onHandled();
}

exports.exchange = function(player, req, resp, onHandled) {
    do {
        if( player.user.status.level < gConfGlobal.TroopMatchOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( isNaN(req.args.id) || isNaN(req.args.num) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var num = parseInt(req.args.num);
        if (num < 1 || num > 999) {
            resp.code = 1; resp.desc = 'invalid num'; break;
        }

        var troopMatch = player.getTroopMatch();
        var shopConf = gConfTroopMatchShop[req.args.id];
        if( !shopConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        if( troopMatch.score < (shopConf.Score * num) ) {
            resp.code = 1; resp.desc = 'not enough score'; break;
        }

        if( troopMatch.max_win < shopConf.Win ) {
            resp.code = 1; resp.desc = 'max_win not reach'; break;
        }

        var material = {};
        var materialNum = num;
        var materialId = shopConf.Material;
        material[materialId] = materialNum;

        player.addInventory('material', materialId, materialNum);

        troopMatch.score -= shopConf.Score * num;
        player.markDirty('troop_match.score');

        resp.data.score = shopConf.Score * num;
        resp.data.material = material;
        
    }while(false);

    onHandled();
}
